//For L1I, it could either read or idle.
//so,

module L1I_TB();
reg CLK,RST;
reg             AQ_V;
reg [7:0]       AQ_ID;
reg [7:0]       AQ_CMD;
reg [15:0]      AQ_BSEL;
reg             AQ_CI;
reg             AQ_WT;
reg [127:0]     AQ_WDATA;
reg [`PADR-1:0] AQ_ADDR;
reg              RQ_ACK;
//Respond Queue
wire             AQ_FULL;
wire             RQ_V;
wire [7:0]       RQ_ID;
wire             RQ_WRERR;
wire             RQ_RDERR;
wire             RQ_RDY;
wire [127:0]     RQ_RDATA;

wire FIBo_V;
wire FIBo_WREN;
wire [7:0] FIBo_ID;
wire FIBo_REQ;
wire [7:0] FIBo_CMD;
wire [3:0] FIBo_BURST;
wire [3:0] FIBo_SIZE;
wire [`PADR-1:0] FIBo_ADDR;
wire [`XLEN-1:0] FIBo_DATA;
    // slave reply
wire FIBi_FULL;
wire FIBi_ACK;
wire FIBi_V;
wire[7:0] FIBi_ID;
wire[7:0] FIBi_RPL;
wire[`XLEN-1:0] FIBi_DATA;


reg [63:0]simmem[512*1024-1:0];
wire [19:0] SRAM_RAddr;
wire [19:0] SRAM_WAddr;
wire SRAM_WBMask;
wire [63:0] SRAM_WData;
wire SRAM_CE;
reg  [63:0] SRAM_RData;

integer pkt_num;

reg             V;
reg [7:0]       ID;
reg [7:0]       CMD;
reg [15:0]     BSEL;
reg             CI;
reg             WT;
reg [127:0]     WDATA;
reg [`PADR-1:0] ADDR;

//TODO: generate AQ Access sequence
//Sweep through Cache depth (4 time) to check the tag is functionally correctly
//Random access with in the access region 
//sweep + random access to check the replace is functionally

//After read, compare simmem data with RQ output
initial 
begin
    for()
end
L1I #(  .CACHE_DEPTH(1024),
        .ENTRY_DEPTH(4),
        .WAY_NUM(4),
        .CACHE_FIBID(8'h01)
    )
DUT (
    .GLB_CLKi(CLK),
    .GLB_RSTi(RST),                      //Cache冲刷请求
    .AQ_V(AQ_V),
    .AQ_ID(AQ_ID),
    .AQ_CMD(AQ_CMD),
    .AQ_BSEL(AQ_BSEL),
    .AQ_CI(AQ_CI),
    .AQ_WT(AQ_WT),
    .AQ_WDATA(AQ_WDATA),
    .AQ_ADDR(AQ_ADDR),
    .AQ_FULL(AQ_FULL),
    .RQ_V(RQ_V),
    .RQ_ID(RQ_ID),
    .RQ_WRERR(RQ_WRERR),
    .RQ_RDERR(RQ_RDERR),
    .RQ_RDY(RQ_RDY),
    .RQ_RDATA(RQ_RDATA),
    .RQ_ACK(RQ_ACK),
    //To FIB
    .L1_FIBo_V(FIBo_V),
    .L1_FIBo_REQ(FIBo_REQ),
    .L1_FIBo_WREN(FIBo_WREN),
    .L1_FIBo_ID(FIBo_ID),
    .L1_FIBo_CMD(FIBo_CMD),
    .L1_FIBo_BURST(FIBo_BURST),
    .L1_FIBo_SIZE(FIBo_SIZE),
    .L1_FIBo_ADDR(FIBo_ADDR),
    .L1_FIBo_DATA(FIBo_DATA),
    // slave reply
    .L1_FIBi_ACK(FIBi_ACK),
    .L1_FIBi_FULL(FIBi_FULL),
    .L1_FIBi_V(FIBi_V),
    .L1_FIBi_ID(FIBi_ID),
    .L1_FIBi_RPL(FIBi_RPL),
    .L1_FIBi_DATA(FIBi_DATA)
    
);
 FIB_L1_Test BUS_PROVIDER
 (
    .VFIBi_CLK(CLK),
    .VFIBi_ARST(RST),
    .VFIBi_V(FIBo_V),
    .VFIBi_ID(FIBo_ID),
    .VFIBi_CMD(FIBo_CMD),
    .VFIBi_BURST(FIBo_BURST),
    .VFIBi_SIZE(FIBo_SIZE),
    .VFIBi_ADDR(FIBo_ADDR),
    .VFIBi_DATA(FIBo_DATA),
    .VFIBo_FULL(FIBi_FULL),
    .VFIBo_V(FIBi_V),
    .VFIBo_ID(FIBi_ID),
    .VFIBo_RPL(FIBi_RPL),
    .VFIBo_DATA(FIBi_DATA),

    .SRAM_RAddr(SRAM_RAddr),
    .SRAM_WAddr(SRAM_WAddr),
    .SRAM_WBMask(SRAM_WBMask),
    .SRAM_WData(SRAM_WData),
    .SRAM_CE(SRAM_CE),
    .SRAM_RData(SRAM_RData)

);

integer seed;

initial  begin seed = $get_initial_random_seed(); end

task AQ_Seq;
	output             V;
	output [7:0]       ID;
	output [7:0]       CMD;
	output [15:0]      BSEL;
	output             CI;
	output             WT;
	output [127:0]     WDATA;
	output [`PADR-1:0] ADDR;
	
	begin
		@(posedge CLK);
		V 		<=	{$random} %2;
		ID 		<=	{$random} %256;
		CMD		<=	{$random} %256;
		BSEL 	<=	$random(seed);
		CI		<=	{$random} %2;
		WT		<=	{$random} %2;
		WDATA	<=  $random(seed);
		ADDR		<=	$random(seed);
	end
endtask

 
task ARQ_Test;
	input             V;
	input [7:0]       ID;
	input [7:0]       CMD;
	input [15:0]      BSEL;
	input             CI;
	input             WT;
	input [127:0]     WDATA;
	input [`PADR-1:0] ADDR;
	
	begin
		@(posedge CLK);
		AQ_V 		<=	V;
		AQ_ID 		<=  ID;
		AQ_CMD		<=	CMD;
		AQ_BSEL 	<=	BSEL;
		AQ_CI		<=	CI;
		AQ_WT		<=	WT;
		AQ_WDATA	<=  WDATA;
		AQ_ADDR		<=	ADDR;
		@(posedge CLK);
		if(ID == RQ_ID && RQ_V)begin
			SRAM_RAddr <= ADDR;
			SRAM_CE       <= 1'b1;
			@(posedge CLK);
			pkt_num = pkt_num + 1;
			if(SRAM_RData == RQ_RDATA)begin
				$display("Success: pkt_num = %d",pkt_num);
			end
			else begin
				$display("Failed: pkt_num = %d",pkt_num);	
			end
		end
	end
	
endtask

endmodule
